#ifndef MANDELBROT_HH_
# define MANDELBROT_HH_

# define MAX_ITER (50)
# include "common.hh"
# include "tbb/task_scheduler_init.h"
# include "tbb/tick_count.h"
# include "tbb/blocked_range2d.h"
# include "tbb/spin_mutex.h"

void Mandelbrot (SDL_Surface*	affichage);

extern SDL_Surface* global_screen;

class MandelbrotParrallel
{
  Uint32* img;
  double minJ;
  double maxJ;
  double minI;
  double maxI;
  double jFactor;
  double iFactor;

 public:
  MandelbrotParrallel (Uint32* img_)
    : img(img_)
    {
      minJ = -2.0;
      maxJ = 1.0;
      minI = -1.2;
      maxI = minI + (maxJ - minJ) * HEIGHT / WIDTH;
      jFactor = (maxJ - minJ) / (WIDTH - 1);
      iFactor = (maxI - minI) / (HEIGHT - 1);
    }

  void operator() (const tbb::blocked_range2d<int>& r) const
  {
    for (int i = r.rows().begin(); i!= r.rows().end(); ++i)
      {
	double currentI = maxI - i * iFactor;

	for (int j = r.cols().begin(); j!= r.cols().end(); ++j)
	  {
	    double currentJ = minJ + j * jFactor;

	    double zI = currentI;
	    double zJ = currentJ;

	    bool isInside = true;

	    for (unsigned iter = 0; iter < MAX_ITER; ++iter)
	      {
		double zI2 = zI * zI;
		double zJ2 = zJ * zJ;

		if (zI2 + zJ2 > 4)
		  {
		    isInside = false;
		    if (iter < MAX_ITER / 2)
		      img[i * WIDTH + j] = SDL_MapRGB(global_screen->format, 0, 0, iter * 511 / MAX_ITER);
		    else
		      img[i * WIDTH + j] = SDL_MapRGB(global_screen->format,
					     (iter - MAX_ITER / 2) * 511 /
					     MAX_ITER,
					     (iter - MAX_ITER / 2) * 511 /
					     MAX_ITER,
					     255);
		    break;
		  }

		zI = 2 * zJ * zI + currentI;
		zJ = zJ2 - zI2 + currentJ;
	      }
	    if (isInside)
	      {
		img[i * WIDTH + j] = SDL_MapRGB(global_screen->format, 0, 0, 0);
	      }

	  }
      }

    if (img == global_screen->pixels)
      {
	tbb::spin_mutex::scoped_lock lock;

	lock.acquire(global_screen_mutex);

	SDL_UpdateRect(global_screen,
		       r.cols().begin(),
		       r.rows().begin(),
		       r.cols().end() - r.cols().begin(),
		       r.rows().end() - r.rows().begin());

	lock.release();
      }

  }
};

#endif /* !MANDELBROT_HH_ */
